#pragma once 
#include "sock.hpp"
#include <sys/select.h>

namespace my_select
{
  class Select
  {
    private:
      int listen_sock;
     unsigned short port;

    public:
      Select(unsigned short _port):port(_port)
    {}
      ~Select()
      {}
    void InitSelect()
    {
      listen_sock=my_sock::Sock::Socket();
      my_sock::Sock::Bind(listen_sock,port);
      my_sock::Sock::Listen(listen_sock,5);
    }
    void Run()
    {
      fd_set rfds;
      int fd_array[1024];//select只能同时等待1024个文件描述符
      Initarray(fd_array,1024);//初始化 文件描述符数组 为-1 

      fd_array[0]=listen_sock;//把监听套接字加入等待就绪事件中 统一是写就绪事件

      for(;;)
      {
        struct timeval timeout={5,0};//设置等待时间
        FD_ZERO(&rfds);//清空 所有的读事件
        int max_fd=-1;//最大文件描述符

        for(int i=0;i<1024;i++)//把所有的有效文件描述符加入读事件中
        {
          if(fd_array[i]==-1)//去除无效的描述符
          {
            continue;
          }

          FD_SET(fd_array[i],&rfds);//添加读事件
          if(max_fd<fd_array[i])//找最大描述符
          {
            max_fd=fd_array[i];
          }
        }

        switch(select(max_fd+1,&rfds,nullptr,nullptr,&timeout))
        {
          case 0:
            std::cout<<"等待时间... "<<timeout.tv_sec<<std::endl;
            break;
          case -1:
            std::cerr<<"select error"<<std::endl;
            break;
          default:
            HandlerEvent(rfds,fd_array,1024);
            break;
        }//end switch 
      }//end for 
    }
    private:
   void Initarray(int arr[],int size)
    {
      for(int i=0;i<size;i++)
      {
        arr[i]=-1;
      }
    }
  void HandlerEvent(fd_set rfds,int fd_array[],int size)
   {
     for(int i=0;i<size;i++)
     {
       if(fd_array[i]==-1)
       {
         continue;
       }

       if(fd_array[i]==listen_sock && FD_ISSET(fd_array[i],&rfds))
       {
         struct sockaddr_in peer;
         socklen_t len=sizeof(peer);

         int sock= accept( fd_array[i] , (struct sockaddr*)&peer , &len);
         if(sock<0)
         {
           std::cerr<<"accept error"<<std::endl;
           continue;
         }

         if(!Addrfds(sock,fd_array,1024))
         {
           close(fd_array[i]);
           std::cerr<<"文件描述符满"<<std::endl;
         }

       }else 
       {
         if(FD_ISSET(fd_array[i],&rfds))
         {
           char buffer[1024];
           ssize_t s=recv(fd_array[i],buffer,sizeof(buffer)-1,0);
           if(s>0)
           {
             buffer[s]=0;
             std::cout<<buffer<<std::endl;
           }else if(s==0)
           {
             std::cerr<<"连接断开"<<std::endl;
             close(fd_array[i]);
             fd_array[i]=-1;
           }else{
             std::cerr << "recv error" << std::endl;
            close(fd_array[i]);
           fd_array[i] = -1;
           }
         }
       }
     }//end for 
   }
  bool Addrfds(int sock,int fd_array[],int size)
  {
    for(int i=0;i<size;i++)
    {
      if(fd_array[i]==-1)
      {
        fd_array[i]=sock;
      return true;
      }
    }
    return false;
  }
  };
}
